package org.eclipseuseradmin.internal.ui;

import java.util.ArrayList;
import java.util.List;

import javax.security.auth.login.LoginContext;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.security.auth.ILoginContext;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipseuseradmin.internal.ui.security.RapLoginContext;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
import org.osgi.service.useradmin.UserAdmin;
import org.osgi.service.useradmin.UserAdminEvent;
import org.osgi.service.useradmin.UserAdminListener;
import org.osgi.util.tracker.ServiceTracker;

/**
 * The activator class controls the plug-in life cycle
 */
public class UserAdminUiPlugin extends AbstractUIPlugin {

	// The plug-in ID
	public static final String PLUGIN_ID = "org.eclipseuseradmin.ui";

	// The shared instance
	private static UserAdminUiPlugin plugin;

	/**
	 * The bundle associated this plug-in
	 */
	private BundleContext context;

	private RoleRootsRegistry roleRootsRegistry;

	private NewUserWizardRegistry newUserWizardRegistry;

	private DefaultUserAdminListener userAdminListener;

	private ServiceRegistration userAdminListenerRegistration;

	private RapLoginContext loginContext;
	
	private ServiceRegistration loginContextRegistration;
	
	private ServiceTracker userAminTracker;

	private ServiceTracker conditionalPermissionAdminTracker;
	
	private ServiceTracker loginContextTracker;
	
	/**
	 * Returns the shared instance
	 * 
	 * @return the shared instance
	 */
	public static UserAdminUiPlugin getDefault() {
		return plugin;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
	 * )
	 */
	public void start(BundleContext context) throws Exception {
		super.start(context);
		plugin = this;
		this.context = context;

		this.roleRootsRegistry = new RoleRootsRegistry();
		this.newUserWizardRegistry = new NewUserWizardRegistry();
		
		this.userAdminListener = new DefaultUserAdminListener();
		this.userAdminListenerRegistration = context.registerService(
				UserAdminListener.class.getName(), userAdminListener, null);

		this.loginContext = new RapLoginContext("USERADMIN", getBundle().getEntry(
				"jaas_config.txt"));
		this.loginContextRegistration = context.registerService(
				ILoginContext.class.getName(), loginContext, null);
		
		this.userAminTracker = new ServiceTracker(context, UserAdmin.class
				.getName(), null);
		this.conditionalPermissionAdminTracker = new ServiceTracker(context,
				ConditionalPermissionAdmin.class.getName(), null);
		this.loginContextTracker = new ServiceTracker(context, ILoginContext.class
				.getName(), null);
		
		userAminTracker.open();
		conditionalPermissionAdminTracker.open();
		loginContextTracker.open();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
	 * )
	 */
	public void stop(BundleContext context) throws Exception {

		userAdminListenerRegistration.unregister();
		loginContextRegistration.unregister();

		this.userAminTracker.close();
		this.conditionalPermissionAdminTracker.close();
		this.loginContextTracker.close();

		plugin = null;
		this.context = null;

		super.stop(context);
	}

	/**
	 * Returns an image descriptor for the image file at the given plug-in
	 * relative path
	 * 
	 * @param path
	 *            the path
	 * @return the image descriptor
	 */
	public static ImageDescriptor getImageDescriptor(String path) {
		return imageDescriptorFromPlugin(PLUGIN_ID, path);
	}

	public static RoleRootsRegistry getRoleRootsRegistry() {
		return getDefault().roleRootsRegistry;
	}

	public static NewUserWizardRegistry getNewUserWizardsRegistry() {
		return getDefault().newUserWizardRegistry;
	}
	
	public static UserAdmin getUserAdmin() {

		return (UserAdmin) getDefault().userAminTracker.getService();
	}
	
	public static ILoginContext getLoginContext() {

		return (ILoginContext) getDefault().loginContextTracker.getService();
	}

	public static void registerUserAdminListener(UserAdminListener listener) {

		getDefault().userAdminListener.getUserAdminListeners().add(listener);
	}

	public static void unregisterUserAdminListener(UserAdminListener listener) {

		getDefault().userAdminListener.getUserAdminListeners().remove(listener);
	}

	public static void log(IStatus status) {
		getDefault().getLog().log(status);
	}

	public static void logErrorMessage(String message) {
		log(new Status(IStatus.ERROR, PLUGIN_ID,
				IUserAdminConstants.INTERNAL_ERROR, message, null));
	}

	public static void logErrorStatus(String message, IStatus status) {
		if (status == null) {
			logErrorMessage(message);
			return;
		}
		MultiStatus multi = new MultiStatus(PLUGIN_ID,
				IUserAdminConstants.INTERNAL_ERROR, message, null);
		multi.add(status);
		log(multi);
	}

	public static void log(Throwable e) {
		log(new Status(IStatus.ERROR, PLUGIN_ID,
				IUserAdminConstants.INTERNAL_ERROR,
				UserAdminUiMessages.get().UserAdminUiPlugin_internal_error, e));
	}

	private class DefaultUserAdminListener implements UserAdminListener {

		private List<UserAdminListener> listeners = new ArrayList<UserAdminListener>();

		public void roleChanged(UserAdminEvent event) {

			for (UserAdminListener listener : listeners) {
				listener.roleChanged(event);
			}
		}

		public List<UserAdminListener> getUserAdminListeners() {
			return listeners;
		}
	}

}
